<template>
  <div>
    <h1 class="title">选择要迁移的数据库对象</h1>
    <el-form ref="form" :model="data">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item
            v-if="
              collect.source.selectType == 2 || collect.source.selectType == 3
            "
            label-width="50px"
            label="源库"
            class="custom-form-item"
            prop="taskName"
          >
            <el-select
              v-model="data.sourceDatabase"
              placeholder="请选择源库"
              size="small"
            >
              <el-option
                v-for="dict in collect.source.nodeTypeOptions"
                :key="dict.value + Math.random()"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item
            v-if="
              collect.source.selectType == 1 || collect.source.selectType == 3
            "
            label-width="100px"
            label="源schema"
            class="custom-form-item"
            prop="taskName"
          >
            <el-select
              v-model="data.sourceDataSchema"
              placeholder="请选择源库"
              size="small"
            >
              <el-option
                v-for="dict in collect.source.nodeTypeOptions"
                :key="dict.value + Math.random()"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item
            v-if="collect.sink.selectType == 2 || collect.sink.selectType == 3"
            label-width="55px"
            label="目标库"
            class="custom-form-item"
            prop="taskName"
          >
            <el-select
              v-model="data.sinkDatabase"
              placeholder="请选择源库"
              size="small"
            >
              <el-option
                v-for="dict in collect.source.nodeTypeOptions"
                :key="dict.value + Math.random()"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item
            v-if="collect.sink.selectType == 1 || collect.sink.selectType == 3"
            label-width="100px"
            label="目标schema"
            class="custom-form-item"
            prop="taskName"
          >
            <el-select
              v-model="data.sinkDataSchema"
              placeholder="请选择源库"
              size="small"
            >
              <el-option
                v-for="dict in collect.source.nodeTypeOptions"
                :key="dict.value + Math.random()"
                :label="dict.label"
                :value="dict.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>
      <el-checkbox-group
        v-model="data.taskTypeScope"
        style="margin-top: 15px"
        size="small"
        :min="1"
      >
        <el-checkbox
          v-for="dict in databaseType"
          :key="dict.value"
          :label="dict.value"
          border
        >{{ dict.label }}</el-checkbox>
      </el-checkbox-group>
    </el-form>

    <div style="text-align: right; margin: 15px 0">
      <el-button
        class="button"
        size="small"
        :disabled="
          data.jobType[1] != 'SYNC_DATA' || data.taskTypeScope.length < 1
        "
        @click.prevent="handleClick"
      >检索和选择表</el-button>
    </div>

    <el-table
      v-if="tableData.length > 0"
      ref="multipleTable"
      v-loading="loading"
      :data="tableData"
      tooltip-effect="dark"
      style="width: 100%; max-height: 400px; overflow-y: auto"
      border
      @selection-change="handleSelectionChange"
    >
      <el-table-column
        type="selection"
        :selectable="checkSelectable"
        width="55"
      />
      <el-table-column
        :filters="databaseType"
        prop="type"
        label="类型"
        width="auto"
      />
      <el-table-column prop="sourceName" label="源表名" width="auto" />
      <el-table-column prop="sourceRows" label="源行数" width="auto" />
      <el-table-column prop="sinkName" label="目标表名" width="auto" />
      <el-table-column prop="sinkRows" label="目标行数" width="auto" />
    </el-table>
  </div>
</template>
<script>
import { stepThreeData } from './index'
import {
  databaseListObjects,
  databaseListDatabaseAndSchema
} from '@/api/console/datasourceInfo'
import Vue from 'vue'

export default {
  // eslint-disable-next-line vue/require-prop-types
  dicts: ['appraise_taskmode', 'synchronous_tasktypescope'],
  props: ['data'],
  data: function() {
    return {
      formElData: [],
      databaseType: [],
      collect: {
        source: {
          nodeTypeOptions: [],
          sourceType: '',
          schemaSelectData: [],
          selectType: 0
        },
        sink: {
          nodeTypeOptions: [],
          sinkType: '',
          schemaSelectData: [],
          selectType: 0
        }
      },
      tableData: [],
      loading: false
    }
  },
  created() {
    this.formElData = stepThreeData
  },
  mounted() {
    this.gainBaseSelect()
    this.assembleDatabase()
  },
  methods: {
    async gainBaseSelect() {
      const {
        start,
        end,
        sourceDatabase,
        sinkDatabase,
        sourceId,
        sinkId,
        sourceDataSchema,
        sinkDataSchema
      } = this.$props.data
      const res = await this.getDicts('datasource_database_type')
      res.data.forEach((f) => {
        if (start === f.dictLabel || end === f.dictLabel) {
          this.collect[start === f.dictLabel ? 'source' : 'sink'].selectType =
            Number(f.dictValue)
        }
      })
      Promise.all([
        databaseListDatabaseAndSchema({
          id: sourceId
        }),
        databaseListDatabaseAndSchema({
          id: sinkId
        })
      ]).then((res) => {
        if (res[0].data.code === 200) {
          this.changeLibraryData(
            res[0].data.data,
            this.collect.source.nodeTypeOptions,
            this.collect.source.schemaSelectData
          )
          if (!sourceDatabase && this.collect.source.selectType !== 1) {
            Vue.set(
              this.$props.data,
              'sourceDatabase',
              res[0].data.data[0].database
            )
          }
          if (!sourceDataSchema && this.collect.source.selectType !== 2) {
            if (this.collect.source.selectType === 1) {
              Vue.set(
                this.$props.data,
                'sourceDataSchema',
                res[0].data.data[0].database
              )
            } else {
              Vue.set(
                this.$props.data,
                'sourceDataSchema',
                res[0].data.data[0].schemas[0]
              )
            }
          }
        }
        if (res[1].data.code === 200) {
          this.changeLibraryData(
            res[1].data.data,
            this.collect.sink.nodeTypeOptions,
            this.collect.sink.schemaSelectData
          )
          if (!sinkDatabase && this.collect.sink.selectType !== 1) {
            Vue.set(
              this.$props.data,
              'sinkDatabase',
              res[1].data.data[0].database
            )
          }
          if (!sinkDataSchema && this.collect.sink.selectType !== 2) {
            if (this.collect.sink.selectType === 1) {
              Vue.set(
                this.$props.data,
                'sinkDataSchema',
                res[1].data.data[0].database
              )
            } else {
              Vue.set(
                this.$props.data,
                'sinkDataSchema',
                res[1].data.data[0].schemas[0]
              )
            }
          }
        }
        if (res[0].data.code !== 200 || res[1].data.code !== 200) {
          this.$message.error(
            `${res[0].data.code !== 200 ? '源库' : '目标库'}:${
              res[res[0].data.code !== 200 ? 0 : 1].data.msg
            }`
          )
        }
        this.elLoading = false
      })
    },
    changeLibraryData(data, value, schemas) {
      if (!data) return
      data.forEach((f) => {
        value.push({
          label: f.database,
          value: f.database
        })
        if (f.schemas) {
          f.schemas.forEach((v) => {
            schemas.push({
              label: v,
              value: v
            })
          })
        }
      })
    },
    async assembleDatabase() {
      let dbType = await this.getDicts('db_object_type')
      const taskTypescope = await this.getDicts('synchronous_tasktypescope')
      const selectData = []
      dbType =
        dbType.data
          .find((f) => f.dictLabel === this.$props.data.start)
          ?.dictValue.split(',') || []
      if (
        this.$props.data.jobMode === 'BATCH' ||
        this.$props.data.jobMode === 'STREAMING'
      ) {
        this.databaseType.push({
          text: 'table',
          label: '表',
          value: 'CREATE_TABLE'
        })
        Vue.set(this.$props.data, 'taskTypeScope', ['CREATE_TABLE'])
        if (this.$props.data.jobType[1] === 'SYNC_DATA') {
          this.handleClick()
        }
        return
      }
      const type = this.$props.data.jobType[0]
      const jobSubType = this.$props.data.jobType[1]
      if (type === 'basic') {
        const subType = jobSubType.split('_')[1]
        taskTypescope.data.forEach((j) => {
          if (j.dictValue.includes(subType)) {
            this.databaseType.push({
              text: j.dictValue,
              label: j.dictLabel,
              value: j.dictValue
            })
          }
        })
      } else if (type === 'common') {
        dbType.forEach((f) => {
          taskTypescope.data.forEach((j) => {
            if (j.dictValue.includes(f.toUpperCase())) {
              this.databaseType.push({
                label: j.dictLabel,
                value: j.dictValue,
                text: j.dictValue
              })
            }
          })
        })
      }
      selectData.push(...this.databaseType.map((f) => f.value))
      if (!this.$props.data.taskTypeScope) {
        Vue.set(this.$props.data, 'taskTypeScope', selectData)
      }
    },
    async handleClick() {
      this.loading = true
      let select = []
      const { selectType } = this.collect.source
      const {
        sourceDatabase,
        sourceDataSchema,
        sinkDataSchema,
        sinkDatabase,
        sourceId,
        sinkId
      } = this.$props.data
      if (
        this.$props.data.taskTypeScope &&
        this.$props.data.taskTypeScope.length === 0
      ) {
        return this.$message('选择任务范围')
      }
      select = this.$props.data.taskTypeScope.map((f) =>
        f.split('_')[1].toLowerCase()
      )
      const dataObj = {
        databaseName:
          selectType === 1 || selectType === 3
            ? sourceDataSchema
            : sourceDatabase,
        taskMode: select.join(','),
        id: sourceId
      }
      let sourceTable = await databaseListObjects(dataObj)
      dataObj.id = sinkId
      dataObj.databaseName =
        this.collect.sink.selectType === 1 || this.collect.sink.selectType === 3
          ? sinkDataSchema
          : sinkDatabase
      let sinkTable = await databaseListObjects(dataObj)
      this.tableData = []
      select.forEach((f) => {
        sourceTable = new Set(sourceTable.data.data[f])
        sinkTable = new Set(sinkTable.data.data[f])
        const combinedTables = [...sourceTable, ...sinkTable]
        combinedTables.forEach((v) => {
          const isSourcePresent = sourceTable.has(v)
          const isSinkPresent = sinkTable.has(v)
          this.tableData.push({
            type: f,
            sourceName: isSourcePresent ? v[`${f}Name`] : '-',
            sourceComment: isSourcePresent ? v.comment : '-',
            sourceRows: isSourcePresent ? v.rows : 0,
            sinkName: isSinkPresent ? v[`${f}Name`] : '-',
            sinkComment: isSinkPresent ? v.comment : '-',
            sinkRows: isSinkPresent ? v.rows : 0
          })
        })
      })
      if (this.$props.data.jdbc && this.$props.data.jdbc.length > 0) {
        this.toggleSelection(this.$props.data.jdbc)
      }
      this.loading = false
    },
    checkSelectable(row, index) {
      return row.sourceName !== '-'
    },
    async handleSelectionChange(v) {
      this.$props.data.jdbc = v
    },
    toggleSelection(rows) {
      if (rows) {
        const that = this
        this.$nextTick(() => {
          that.tableData.forEach((f) => {
            rows.forEach((row) => {
              if (
                f.sourceName === (row.name || row.tableName || row.sourceName)
              ) {
                this.$refs.multipleTable.toggleRowSelection(f, true)
              }
            })
          })
        })
      } else {
        this.$refs.multipleTable.clearSelection()
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.title {
  color: #333;
  font-size: 22px;
  line-height: 1.25;
  font-family: alimama, webfont-notdef;
  font-size: 18px;
  box-sizing: border-box;
  font-weight: 600;
  margin: 25px 0;
  text-align: left;
}

::v-deep .el-form-item__label {
  font-family: alimama, webfont-notdef;
  color: #333;
  text-align: left;
}

.tips {
  font-size: 14px;
  font-weight: 600;
  margin: 5px 0;
}

::v-deep .el-checkbox__input {
  vertical-align: bottom;
}

::v-deep .el-checkbox.is-bordered.el-checkbox--small {
  padding-top: 8px !important;
}

::v-deep .el-table .el-table__header-wrapper th {
  background-color: #fff;
}

.button {
  background-color: rgb(231, 237, 241);
  color: #222;
  font-size: 14px;
  border: 1px solid rgb(231, 237, 241);

  &:hover {
    background-color: rgb(231, 237, 241);
    border: 1px solid #aaa;
  }
}
</style>
